class MyPromise {
  constructor(exector) {
    // 初始化状态及初始值
    this.initValue();
    // 初始化的时候改变 this 指向，将 this 指向实例对象
    this.initBind();
    // 执行器，当 new MyPromise()时，这个callback要接受 resolve 和 reject 函数
    try {
      // 正常执行的话，执行 exector
      exector(this.resolve, this.reject);
    } catch (error) {
      // 捕获到异常，则执行一次 reject
      this.reject(error);
    }
  }
  initValue() {
    this.PromiseState = "pending"; // Promise 状态
    this.PromiseResult = null; // Promise 返回值
    this.onFulfilledCallbacks = []; // 保存成功的回调
    this.onRejectedCallbacks = []; // 保存失败的回调
  }
  initBind() {
    this.resolve = this.resolve.bind(this);
    this.reject = this.reject.bind(this);
  }
  resolve(value) {
    // 只要状态已经改变，就不允许继续修改状态
    if (this.PromiseState !== "pending") {
      return;
    }
    // 此时状态改为 fulfilled
    this.PromiseState = "fulfilled";
    // 将传递进来的参数赋值
    this.PromiseResult = value;
    // 执行成功的回调
    while (this.onFulfilledCallbacks.length) {
      // 每次从队列中取出一个来执行
      this.onFulfilledCallbacks.shift()(this.PromiseResult);
    }
  }
  reject(reason) {
    // 只要状态已经改变，就不允许继续修改状态
    if (this.PromiseState !== "pending") {
      return;
    }
    // 此时状态改为 rejected
    this.PromiseState = "rejected";
    // 将传递进来的错误抛出
    this.PromiseResult = reason;
    // 执行成功的回调
    while (this.onRejectedCallbacks.length) {
      // 每次从队列中取出一个来执行
      this.onRejectedCallbacks.shift()(this.PromiseResult);
    }
  }
  then(onFulfilled, onRejected) {
    // then 函数接收两个callback，一个是成功回调，一个是失败回调
    // 参数兜底处理，确保返回的都是回调函数
    onFulfilled =
      typeof onFulfilled === "function" ? onFulfilled : (value) => value;
    onRejected =
      typeof onRejected === "function"
        ? onRejected
        : (reason) => {
            throw reason;
          };
    var promiseThen = new MyPromise((resolve, reject) => {
      const handlePromise = (fn) => {
        setTimeout(() => {
          try {
            let f = fn(this.PromiseResult);
            if (f === promiseThen) {
              // 不能返回自身
              throw new Error("不能返回自身。。。");
            }
            if (f instanceof MyPromise) {
              // 如果是 Promise 则执行对应的回调
              f.then(resolve, reject);
            } else {
              // 如果不是 Promise 则直接成功
              resolve(f);
            }
          } catch (error) {
            // 处理报错, 预防一些边界情况
            reject(error);
            throw new Error(error);
          }
        });
      };
      // 如果成功，则执行成功回调
      // 如果失败，则执行失败回调
      if (this.PromiseState === "fulfilled") {
        // onFulfilled(this.PromiseResult);
        handlePromise(onFulfilled);
      } else if (this.PromiseState === "rejected") {
        // onRejected(this.PromiseResult);
        handlePromise(onRejected);
      } else if (this.PromiseState === "pending") {
        // 将成功回调放入队列
        this.onFulfilledCallbacks.push(handlePromise.bind(this, onFulfilled));
        // 将失败回调放入队列
        this.onRejectedCallbacks.push(handlePromise.bind(this, onRejected));
      }
    });

    // 返回包装的 Promise
    return promiseThen;
  }
  static all(promises) {
    const result = [];
    let count = 0;
    return new MyPromise((resolve, reject) => {
      const addData = (index, value) => {
        result[index] = value;
        count++;
        if (count === promises.length) resolve(result);
      };
      promises.forEach((promise, index) => {
        if (promise instanceof MyPromise) {
          promise.then(
            (res) => {
              addData(index, res);
            },
            (err) => reject(err)
          );
        } else {
          addData(index, promise);
        }
      });
    });
  }

  static race(promises) {
    return new MyPromise((resolve, reject) => {
      promises.forEach((promise, index) => {
        if (promise instanceof MyPromise) {
          promise.then(
            (res) => resolve(res),
            (err) => reject(err)
          );
        } else {
          resolve(promise);
        }
      });
    });
  }

  static allSettled(promises) {
    return new MyPromise((resolve, reject) => {
      let result = [];
      let count = 0;
      let addData = (status, value, index) => {
        result[index] = {
          status,
          value,
        };
        count++;
        if (count === promises.length) {
          resolve(result);
        }
      };
      promises.forEach((promise, index) => {
        if (promise instanceof MyPromise) {
          promise.then(
            (res) => addData("fulfilled", res, index),
            (err) => addData("rejected", err, index)
          );
        } else {
          addData("fulfilled", promise, index);
        }
      });
    });
  }

  static any(promises) {
    return new MyPromise((resolve, reject) => {
      let count = 0;
      promises.forEach((promise, index) => {
        if (promise instanceof MyPromise) {
          promise.then(
            (res) => resolve(res),
            (err) => {
              count++;
              if (count === promises.length) {
                reject("都执行失败了~");
              }
            }
          );
        }
      });
    });
  }
}
const p1 = new MyPromise((resolve, reject) => {
  reject(1);
});
const p2 = new MyPromise((resolve, reject) => {
  reject(2);
});

MyPromise.any([p1, p2]).then((res) => {
  console.log(res);
});
